package com.example.devecohp;

import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class TestRules  extends AnAction {
    @Override
    public void actionPerformed(@NotNull AnActionEvent anActionEvent) {
        Pattern pattern = Pattern.compile("/\\* HPAudit: (.*?) : (.*?) : (.*?) : (.*?) : (.*?) \\*/");
        VirtualFile virtualFile=anActionEvent.getData(CommonDataKeys.VIRTUAL_FILE);
        if(virtualFile==null){
            return;
        }
        PsiDirectory directory = PsiManager.getInstance(anActionEvent.getProject()).findDirectory(virtualFile);
        List<PsiFile> allFiles;
        allFiles = AuditAllFiles.getAllFiles(directory);
        String[] rules = new String[]{
                "hp-arkui-async-load",
                "hp-arkui-component-async-load",
                "hp-arkui-set-list-width-height",
                "hp-arkui-limit-refresh-scope",
                "hp-arkui-load-on-demand",
                "hp-arkui-no-flex",
                "hp-arkui-no-high-freq-log",
                "hp-arkui-no-redundant-nest",
                "hp-arkui-optimize-nest-levels",
                "hp-arkui-reduce-view-nest-level",
                "hp-arkui-same-animateto-same-params",
                "hp-performance-args-match-params",
                "hp-performance-initialize-obj-props",
                "hp-performance-no-closures",
                "hp-performance-no-const-prop-in-heavy-loop",
                "hp-performance-no-deep-nested-components",
                "hp-performance-no-delete-objs-props",
                "hp-performance-no-dynamic-cls-func",
                "hp-performance-no-float-number",
                "hp-performance-no-obj-props-dynamic",
                "hp-performance-no-type-annotation",
                "hp-performance-objs-using-literals",
                "hp-performance-proper-data-structures",
                "hp-performance-unchanged-const-vars",
                "hp-specs-dec-num",
                "hp-specs-dot-notation-for-obj-props",
                "hp-specs-enum-ucase-uscore",
                "hp-specs-explicit-return-types",
                "hp-specs-lcamelcase-vars-funcs-params",
                "hp-specs-no-any",
                "hp-specs-no-await-non-thenables",
                "hp-specs-no-dynamic-funcs",
                "hp-specs-no-equality-ops-floating",
                "hp-specs-no-eval",
                "hp-specs-no-finally-end-abnormally",
                "hp-specs-no-modify-prototypes",
                "hp-specs-no-multi-vars-single-line",
                "hp-specs-no-negative-bool-vars-funcs",
                "hp-specs-no-non-numeric-props-arrays",
                "hp-specs-no-return-await",
                "hp-specs-no-return-undefined",
                "hp-specs-no-this-to-vars",
                "hp-specs-no-vars-control-condition-expns",
                "hp-specs-no-with",
                "hp-specs-null-undefined-independent-types",
                "hp-specs-strict-equality-ops",
                "hp-specs-ucamelcase-cls-enums-ns",
                "hp-specs-use-braces-stmts-loops",
                "hp-specs-use-const-or-let-for-vars",
                "hp-specs-use-rest-params",
                "hp-specs-use-strict-mode",
                "hp-specs-use-type-exports",
                "hp-specs-use-type-imports",
                "hp-specs-wrap-long-lines"
};
        //String rule = "hp-arkui-async-load";
        HashMap<PsiFile,List<String>> full_result = new HashMap<>();
        for (PsiFile psiFile : allFiles){
            List<String> full = Auditor.runAndGetOutput(new String[]{"hpaudit", psiFile.getVirtualFile().getPath()});
            full_result.put(psiFile,full);
        }
            int count = 0;
                for(String rule:rules) {

                    HashSet<String> result = new HashSet<>();
                    HashSet<String> should = new HashSet<>();
                    for (PsiFile psiFile : allFiles) {
                count++;
                //System.out.println(count + "/" + allFiles.size()* rules.length);
                List<String> res = Auditor.runAndGetOutput(new String[]{"a.bat", rule, psiFile.getVirtualFile().getPath()});
                List<String> full = full_result.get(psiFile);
                if (res == null || full == null) {
                    continue;
                }
                for (String r : res) {
                    Matcher matcher = pattern.matcher(r);
                    if (matcher.find()) {
                        String ruleName = matcher.group(2);
                        //System.out.println(matcher.group(5));
                        if (ruleName.equals(rule)) {
                            result.add(matcher.group(5).trim());
                        }

                    }
                }
                for (String r : full) {
                    Matcher matcher = pattern.matcher(r);
                    if (matcher.find()) {
                        String ruleName = matcher.group(2);
                        //System.out.println(ruleName);
                        if (ruleName.equals(rule)) {
                            should.add(matcher.group(5).trim());
                        }

                    }
                }
            }

            //System.out.println(result);
            //System.out.println(should);
                System.out.println(rule);
                print_diff(result,should);
        }

    }
    private void print_diff(HashSet<String>result, HashSet<String>should){

        HashSet<String> result1 = new HashSet<>(result);
        HashSet<String> should1 = new HashSet<>(should);
        result1.removeAll(should);
        System.out.println(result1);
        should1.removeAll(result);
        System.out.println(should1);
        should1.addAll(result1);
        System.out.println(should1);
    }
}
